package com.cellulam.framework.scaffold.generate;

import com.cellulam.framework.scaffold.generate.db.TableMetaInfo;
import com.cellulam.framework.scaffold.generate.utils.GenUtils;
import com.cellulam.framework.scaffold.generate.project.MavenModuleInfo;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class FtlProcessor {

    static Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);

    static {
        setTemplateDir("/template");
    }

    public void addRootMap(Object key, Object value){
        this.root.put(key, value);
    }

    private MavenModuleInfo module;
    private String ftlResourcePath;
    private String targetFileName;
    private boolean doOverride;

    private boolean useResourcePath;
    private String subResourceDir;
    private Map root = new HashMap();

    public FtlProcessor(MavenModuleInfo module, String ftlResourcePath, String targetFileName, boolean doOverride) {
        this.module = module;
        this.ftlResourcePath = ftlResourcePath;
        this.targetFileName = targetFileName;
        this.doOverride = doOverride;
    }

    public static void setTemplateDir(String packagePath) {
        cfg.setClassForTemplateLoading(FtlProcessor.class, packagePath);
        System.out.println("setTemplateDir packagePath is " + packagePath);
    }

    public FtlProcessor addProperty(String name, Object obj) {
        root.put(name, obj);
        return this;
    }

    public FtlProcessor useResourcePath(String subResourceDir) {
        this.subResourceDir = subResourceDir;
        this.useResourcePath = true;
        return this;
    }

    public String getGenerateDir() {
        if (useResourcePath) {
            return module.resourcesPath(subResourceDir);
        } else {
            return module.fullPackagePath();
        }
    }

    public void process(TableMetaInfo table) throws Exception {
        File filePath = new File(getGenerateDir() + "/" + targetFileName);

        if (filePath.exists() ) {
            if (doOverride) {
                filePath.delete();
                GenUtils.info("DELETE file " + filePath.getName(), "\t\t");
            } else {
                GenUtils.info("CAN NOT override " + filePath.getName(), "\t\t");
                return;
            }
        }

        root.put("table", table);
        root.put("module", module);
        root.put("loginUser", System.getProperty("user.name"));
        root.put("generateDate", DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.now()));


        if (!filePath.getParentFile().exists()) {
            filePath.getParentFile().mkdirs();
            GenUtils.info("create directory " + filePath.getParentFile() + "", "\t\t");
        }

        Template template = cfg.getTemplate(ftlResourcePath);
        Writer out = new OutputStreamWriter(new FileOutputStream(filePath));
        template.process(root, out);
        out.flush();
        out.close();
        GenUtils.info("create file " + filePath, "\t\t");
    }

    public void delete() throws Exception {
        File filePath = new File(getGenerateDir() + "/" + targetFileName);

        if (filePath.exists() ) {
            filePath.delete();
            GenUtils.info("DELETE file " + filePath.getName(), "\t\t");
        } else {
            GenUtils.info("DO NOT exist " + filePath.getName(), "\t\t");
        }
    }

}
